package com.example.demo.aop;


import com.example.demo.utils.RequestIpUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.text.MessageFormat;

/**
 * 日志切面类
 * @author gaobing
 * @date 2020/08/01
 * @since 1.0.0
 */
@Aspect
@Component
@Slf4j
public class LogAspect {
    @Autowired
    private ObjectMapper objectMapper;

    @Around("execution(* com.example.demo.controller..*.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object[] args = joinPoint.getArgs();
        StringBuilder logInfo = new StringBuilder();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String path = request.getRequestURI();

        logInfo.append("\n").append(MessageFormat.format("访问地址: {0} ", path)).append("\n");
        logInfo.append(MessageFormat.format("请求IP: {0}", RequestIpUtils.getIpAddr(request))).append("\n");
        String params = "";
        try {
            if (args[0] instanceof MultipartFile) {
                MultipartFile file = (MultipartFile) args[0];
                params = file.getOriginalFilename();
            } else if (RequestMethod.POST.toString().equalsIgnoreCase(request.getMethod())){
                params = objectMapper.writeValueAsString(args);
            } else if (RequestMethod.GET.toString().equalsIgnoreCase(request.getMethod())) {
                params = request.getQueryString();
            }
            logInfo.append(MessageFormat.format("请求参数为: {0}", params)).append("\n");
        } catch (Exception e) {
            logInfo.append("请求参数类型暂时不支持解析!").append("\n");
        }

        String resultStr = "";
        // 执行方法
        Object result;
        try {
            // 执行方法
            result = joinPoint.proceed();
            resultStr = objectMapper.writeValueAsString(result);
        } finally {
            logInfo.append(MessageFormat.format("响应结果为: {0}", resultStr)).append("\n");
            long endTime = System.currentTimeMillis();
            logInfo.append(MessageFormat.format("请求响应时间为: {0}ms", String.valueOf(endTime - startTime)));
            log.info(logInfo.toString());
        }
        return result;
    }
}